const fs = require('fs').promises;
const path = require('path');

function* read() {
  // throw '123' //TODO notice 1 会走co里的try catch

  // 这个try catch是木有必要的↓
  //↓使用co库后，yield的那个promise如果reject就会直接把co reject掉
  // try {
    let content = yield fs.readFile(path.resolve(__dirname,'name1.txt'), 'utf8');
    let age = yield fs.readFile(path.resolve(__dirname,content.trim()), 'utf8');
    return age

    //TODO notice 2↓ 情景二
    // 如果用户没有使用try catch捕获，
    // 这里返回的promise如果reject的话 则会直接走 co.catch
    // (co系统会自动识别 如果用户没有手动给一个yield报上try catch, 那么在内部就不会调用it.throw, 而是直接reject掉co)
    /*yield new Promise((resolve, reject) => {
      setTimeout(() => {
        reject(123456)
      }, 100)
    })*/

  // }catch (e) {
  //   console.log('我是生成器里的try catch');
  //   console.log(e);
  // }

  console.log('end');
}

/*let co = require('co');
co(read()).then(data => {
  console.log('co then success data结果:', data);
}, err => {
  console.log('co then reject');
  console.log(err);
});*/
/*
co then reject
123456
*/


function co(it) {
  return new Promise((resolve, reject) => {
    function next(data) {
      //TODO notice 1↓
      try {
        var {value, done} = it.next(data);
      } catch (e) {
        console.log('我是co里的try catch');
        reject(e);
      }

      if (done) {
        resolve(value);
      } else {
        Promise.resolve(value).then(data => {
          next(data);
        }, err => { // 如果出错将错误抛出来
          console.log('it.throw(err)');
          //↓ TODO notice 2
          // it.throw(err);

          reject(err) //reject还是it.throw取决用户是否主动try catch（没有就直接reject）
          //↑ TODO notice 2
        })
      }
    }

    next();
  })
}
co(read()).then(data => {
  console.log('co then success data结果:', data);
}, err => {
  console.log('co then reject');
  console.log(err);
});
